#include "Serialization.h"

namespace FinalRendering
{
	namespace Engine
	{
		using namespace GxMetaParser;

		void PrintTab(StringBuilder & sb, int level)
		{
			for (int i=0; i<level; i++)
				sb.WriteChar(L'\t');
		}

		void NewLine(StringBuilder & sb, int level)
		{
			sb.WriteChar(L'\n');
			PrintTab(sb, level);
		}

		void WriteInt(StringBuilder & sb, int level, const String & name, int value)
		{
			NewLine(sb, level);
			sb.WriteString(name);
			sb.WriteChar(L' ');
			sb.WriteString(String((int)value));
		}

		void WriteFloat(StringBuilder & sb, int level, const String & name, float v)
		{
			NewLine(sb, level);
			sb.WriteString(name);
			sb.WriteChar(L' ');
			sb.WriteString(String(v, 3));
		}	

		void WriteString(StringBuilder & sb, int level, const String & name, String & str)
		{
			NewLine(sb, level);
			sb.WriteString(name);
			sb.WriteString(L" \"");
			sb.WriteString(str);
			sb.WriteChar(L'\"');
		}

		void WriteVector(StringBuilder & sb, vec3 & v)
		{
			sb.WriteString(String(v.x, 3));
			sb.WriteChar(L',');
			sb.WriteString(String(v.y, 3));
			sb.WriteChar(L',');
			sb.WriteString(String(v.z, 3));
		}

		void BlockBegin(StringBuilder & sb, int & level)
		{
			NewLine(sb, level);
			sb.WriteChar(L'{');
			level ++;
		}

		void BlockEnd(StringBuilder & sb, int & level)
		{
			level --;
			NewLine(sb, level);
			sb.WriteChar(L'}');
		}

		TokenNode * ReadToken(TokenNode *& token, Lex::TokenType type)
		{
			if (token && token->Data.TypeID == (int)type)
			{
				TokenNode * rs = token;
				token = token->GetNext();
				return rs;
			}
			throw 0;
		}

		TokenNode * ReadInt(TokenNode *& token, int * val)
		{
			TokenNode * tk = ReadToken(token, Lex::Int);
			*val = tk->Data.Str.ToInt();
			return tk;
		}

		TokenNode * ReadFloat(TokenNode *& node, float * val)
		{
			TokenNode * token = ReadToken(node, Lex::Float);
			*val = token->Data.Str.ToFloat();
			return token;
		}

		TokenNode * ReadString(TokenNode *& node, String * val)
		{
			TokenNode * token = ReadToken(node, Lex::String);
			*val = token->Data.Str.Mid(1,token->Data.Str.GetLength()-2);
			return token;
		}

		void ReadVector(TokenNode *& node, vec3 * v)
		{
			ReadFloat(node, &v->x);
			ReadToken(node, Lex::Comma);
			ReadFloat(node, &v->y);
			ReadToken(node, Lex::Comma);
			ReadFloat(node, &v->z);
		}

	}
}